﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

public abstract class AItemStorage
{
    //可堆叠物品的最大堆叠数量
    private const int MAX_NUM = 9;

    public int Capacity
    {
        get
        {
            return ItemArray.Length;
        }
        set
        {
            Item[] newArray = new Item[value];
            if (itemArray != null)
            {
                itemArray.CopyTo(newArray, 0);
            }
            itemArray = newArray;
        }
    }
    private Item[] itemArray;
    public Item[] ItemArray
    {
        get
        {
            if (itemArray == null)
            {
                throw new Exception("使用ItemStorage容器前必须对Capacity赋值,以初始化容器");
            }
            else
            {
                return itemArray;
            }
        }
        private set { itemArray = value; }
    }
    /// <summary>
    /// 仅用于序列化还原!!!
    /// </summary>
    public AItemStorage()
    {
    }

    public event Action OnItemsChange;

    //增加
    public void Add(Item item)
    {
        if (GetItemType(item.id) != 1)//可以堆叠物品
        {
            //判断是否能放进去
            Item putItem = item;
            if (putItem.num > MAX_NUM) throw new Exception("Item的num大于对大堆叠数量");

            //遍历每一个格子
            for (int i = 0; i < ItemArray.Length; i++)
            {
                //空格子就直接把Item放进去
                if (ItemArray[i] == null)
                {
                    UnityEngine.Debug.Log("放入空格子:" + i);
                    ItemArray[i] = putItem;
                    putItem.index = i;
                    break;//跳出循环
                }
                else
                {
                    //判断格子上的物品是否为GeneralItem
                    Item currentItem = ItemArray[i];
                    //----不是GeneralItem
                    if (GetItemType(currentItem.id) == 1) continue;

                    //不是同样物品就跳过
                    if (currentItem.id != putItem.id) continue;

                    //可以放进去的数量
                    int canPutNum = MAX_NUM - currentItem.num;
                    if (canPutNum < putItem.num)//放不下
                    {
                        currentItem.num = MAX_NUM;
                        putItem.num -= canPutNum;
                    }
                    else//放得下
                    {
                        currentItem.num += putItem.num;
                        putItem.num = 0;//有GC
                        break;//跳出循环
                    }
                }
            }
        }
        else //特殊物品
        {
            for (int i = 0; i < ItemArray.Length; i++)
            {
                if (ItemArray[i] == null)
                {
                    ItemArray[i] = item;
                    item.index = i;
                    break;
                }
            }
        }
        OnItemsChange?.Invoke();
    }
    //移除
    public void Remove(Item item)
    {
        if (GetItemType(item.id) != 1)//可以堆叠物品
        {
            Item removeItem = item;
            if (removeItem.num > MAX_NUM) throw new Exception("Item的num大于对大堆叠数量");
            for (int i = ItemArray.Length - 1; i >= 0; i--)
            {
                Item currentItem = ItemArray[i];
                if (currentItem == null) continue;//跳过空格子
                //不是GeneralItem或不是同样物品就跳过
                if (GetItemType(currentItem.id) == 1 || currentItem.id != removeItem.id) continue;
                //不够减
                if (currentItem.num < removeItem.num)
                {
                    removeItem.num -= currentItem.num;//currentItem有GC
                    ItemArray[i] = null;
                }
                else//够减
                {
                    currentItem.num -= removeItem.num;
                    removeItem.num = 0;//有GC
                    if (currentItem.num == 0) ItemArray[i] = null;
                }
            }
        }
        else//特殊物品
        {
            for (int i = 0; i < ItemArray.Length; i++)
            {
                if (ItemArray[i] == item)
                {
                    ItemArray[i] = null;
                    break;
                }
            }
        }
        OnItemsChange?.Invoke();
    }

    //整理

    //查有没有
    public bool ContiansSpcialItem(Item item)
    {
        return Array.IndexOf(ItemArray, item) != -1;
    }

    public Item FindSpecialItem(int configID, int specialID)
    {
        for (int i = 0; i < ItemArray.Length; i++)
        {
            if (ItemArray[i] == null)
            {
                continue;
            }

            Item specialItem = ItemArray[i];
            if (GetItemType(specialItem.id) == 1 && specialItem.id == configID && specialItem.SpecialID == specialID)
            {
                return specialItem;
            }
        }
        return null;
    }

    public Item this[int index]
    {
        get { return ItemArray[index]; }
    }

    public Item GetItemAt(int index)
    {
        return ItemArray[index];
    }

    //是否还能放普通物品
    private bool AddGeneralIteAble(Item putItem)
    {
        int num = 0;
        //从后往前找可以放入的个数,空=最大堆叠
        for (int i = ItemArray.Length - 1; i >= 0; i--)
        {
            if (ItemArray[i] == null) num += MAX_NUM;//空格子
            else
            {
                Item currentItem = ItemArray[i] as Item;
                //不是GeneralItem或不是同样物品就跳过
                if (GetItemType(currentItem.id) == 1 || currentItem.id != putItem.id) continue;
                num += MAX_NUM - currentItem.num;
            }
            if (num >= putItem.num) return true;
        }
        return false;
    }

    /// <summary>
    /// 子类重写此方法通过差表获取物品id
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    public abstract int GetItemType(int id);
}

#if 用法
internal class DataCenter
{
    private ItemStorage Packge;//背包
    private ItemStorage Repository;//仓库
}
#endif